package com.chenfan.magic.interpreter;

import com.chenfan.magic.core.IdcEngineEntry;
import com.chenfan.magic.core.MagicLogPublisher;
import com.chenfan.magic.entity.TTLDetailModel;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.Map;

/**
 * Groovy动态解释器
 * <p>
 * 示例: run("def handler(language) {return \"Hello $language\"}", paramMap);
 *
 * @author caohui
 */
@Slf4j
@Component
@AllArgsConstructor
public class GroovyInterpreter implements __IInterpreter {

    public static final String TYPE_CODE = "groovy";
    public static final String ALIAS = "gro";

    @Override
    public Object run(Map<String, Object> idcRuntimePool, String code, Map<String, Object> paramMap) {
        TTLDetailModel ttlDetailModel = new TTLDetailModel();
        ttlDetailModel.start();
        Object result = null;
        try {
            ScriptEngine engine = new ScriptEngineManager().getEngineByName(TYPE_CODE);
            engine.eval(code);
            if (engine instanceof Invocable) {
                Invocable inv = (Invocable) engine;
                result = inv.invokeFunction(__IInterpreter.HANDER_NAME, paramMap);
            }
            MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, code, result, paramMap, ttlDetailModel.end().getTtl() + "");
        } catch (Exception e) {
            e.printStackTrace();
            IdcEngineEntry.throwException(idcRuntimePool, null, e);
            MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, code, result, paramMap, ttlDetailModel.end().getTtl() + "", e);
        }
        return result;
    }

    @Override
    public Object run(Map<String, Object> idcRuntimePool, String expression, String defaultValue) {
        return defaultValue;
    }

    public static void main(String[] args) {
        Map<String, Object> paramMap = Maps.newHashMap();
        String code = "def handler(scope) {\n" +
                "    def departs = scope[\"departs\"];\n" +
                "    def childrens = scope[\"children\"];\n" +
                "    departs.each { depart -> \n" +
                "      def inchilds = [];\n" +
                "      childrens.each { children ->\n" +
                "        if(children.dept_id == depart.dept_id){\n" +
                "          inchilds.add(children);\n" +
                "        }\n" +
                "      }\n" +
                "      depart.put(\"children\", departs);\n" +
                "    }\n" +
                "    return departs;\n" +
                "  }";
        code = "def handler(language) {return \"Hello $language\"}";
        try {
            ScriptEngine engine = new ScriptEngineManager().getEngineByName(TYPE_CODE);
            engine.eval(code);
            if (engine instanceof Invocable) {
                Invocable inv = (Invocable) engine;
                Object result = inv.invokeFunction(__IInterpreter.HANDER_NAME, paramMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
